package com.imau.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imau.bean.Role;
import com.imau.bean.SysDept;
import com.imau.bean.User;
import com.imau.bean.UserRole;
import com.imau.common.utils.SqlSessionFactoryUtil;
import com.imau.common.utils.StringLike;
import com.imau.mapper.RoleMapper;
import com.imau.mapper.SysDeptMapper;
import com.imau.mapper.UserMapper;
import com.imau.mapper.UserRoleMapper;
import com.imau.service.UserService;
import io.mybatis.mapper.example.Example;
import io.mybatis.service.AbstractService;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.*;

public class UserServiceImpl extends AbstractService<User, String, UserMapper> implements UserService {


    /**
     * 角色用户中间表Dao
     */
    private UserRoleMapper userRoleMapper;

    private RoleMapper roleMapper;

    private SysDeptMapper deptMapper;

    private UserMapper userMapper;

    private SqlSession session;

    /**
     * 关闭session
     */
    private void closeMapper() {

        if (session != null) {
            session.close();
        }
    }

    /**
     * 初始化 Mapper 对象
     */
    private void initMapper() {


        SqlSessionFactory factory = SqlSessionFactoryUtil.getInstace();

        session = factory.openSession(true);
        userMapper = session.getMapper(UserMapper.class);
        baseMapper = session.getMapper(UserMapper.class);
        deptMapper = session.getMapper(SysDeptMapper.class);
        userRoleMapper = session.getMapper(UserRoleMapper.class);

        roleMapper = session.getMapper(RoleMapper.class);
    }


    @Override
    public User save(User user) {

        initMapper();
        //1.保存用户
        User save = super.save(user);

        //2.维护中间表


        assignRoles(user.getId(),user.getRoles());

        closeMapper();

        return save;

    }

    @Override
    public int deleteById(String id) {

       initMapper();

       //删除用户
        int i = baseMapper.deleteByPrimaryKey(id);

        //删除中间表
        i+= userRoleMapper.delete(new UserRole(id));

       closeMapper();

        return i;
    }

    @Override
    public int updateUser(User user) {


        initMapper();

        int i = baseMapper.updateByPrimaryKey(user);

        //重新分配角色
       this.assignRoles(user.getId(),user.getRoles());

        closeMapper();
        return i;
    }

    @Override
    public User findById(String id) {

        initMapper();

        //1.查询用户

        User user = super.findById(id);

        if(user == null)
        {
            return null;
        }



        //2.用户的did 查询部门信息
        //https://blog.csdn.net/qq_38766930/article/details/126757469  java8新特性
        Optional<SysDept> optional = deptMapper.selectByPrimaryKey(user.getDid());
        //判断不为空
        if(optional.isPresent())
        {
            user.setDept(optional.get());
        }




        //3. 给用户赋值角色信息

        //3.1 用用户id，从中间表查询出角色ids

        List<UserRole> userRoles = userRoleMapper.selectByFieldList(UserRole::getUserId, Arrays.asList(id));

        //3.2 在从角色表查询出对象

        Set<Role> set = new HashSet<>();

        for (UserRole ur : userRoles) {

            //封装角色 - > 权限关联
            Role role = roleMapper.selectByRoleID(ur.getRoleId());

            set.add(role);

        }

        user.setRoles(set);


        closeMapper();

        return user;
    }

    @Override
    public User findByField(User entiry) {

        initMapper();
        //调用父接口的方法
        User user = this.baseMapper.selectOne(entiry).get();

        if(user == null)
        {
            return null;
        }



        //2.用户的did 查询部门信息
        //https://blog.csdn.net/qq_38766930/article/details/126757469  java8新特性
        Optional<SysDept> optional = deptMapper.selectByPrimaryKey(user.getDid());
        //判断不为空
        if(optional.isPresent())
        {
            user.setDept(optional.get());
        }


        //3. 给用户赋值角色信息

        //3.1 用用户id，从中间表查询出角色ids

        List<UserRole> userRoles = userRoleMapper.selectByFieldList(UserRole::getUserId, Arrays.asList(user.getId()));

        //3.2 在从角色表查询出对象

        Set<Role> set = new HashSet<>();

        for (UserRole ur : userRoles) {

            Role role = roleMapper.selectByPrimaryKey(ur.getRoleId()).get();

            set.add(role);

        }

        user.setRoles(set);
        closeMapper();




        return user;
    }

    @Override
    public User findByMobile(String mobile) {

        initMapper();
        //调用付结构
        User user = this.userMapper.selectByMobileUser(mobile);

        if(user == null)
        {
            return null;
        }



        //2.用户的did 查询部门信息
        //https://blog.csdn.net/qq_38766930/article/details/126757469  java8新特性
        Optional<SysDept> optional = deptMapper.selectByPrimaryKey(user.getDid());
        //判断不为空
        if(optional.isPresent())
        {
            user.setDept(optional.get());
        }


        //3. 给用户赋值角色信息

        //3.1 用用户id，从中间表查询出角色ids

        List<UserRole> userRoles = userRoleMapper.selectByFieldList(UserRole::getUserId, Arrays.asList(user.getDid()));

        //3.2 在从角色表查询出对象

        Set<Role> set = new HashSet<>();

        for (UserRole ur : userRoles) {

            Role role = roleMapper.selectByPrimaryKey(ur.getRoleId()).get();

            set.add(role);

        }

        user.setRoles(set);
        closeMapper();




        return user;
    }

    @Override
    public PageInfo<User> queryListByPagte(User user, int currentPage, int size) {

        initMapper();

        //1. 查询前构建分页对象

        PageHelper.startPage(currentPage, size);

        //2. 构建查询参数

        //2.1 创建 example 对象
        Example<User> example = new Example<User>();

        //2.2 创建 动态拼接Sql对象
        Example.Criteria<User> criteria = example.createCriteriaSelective();

        if (user != null) {
            criteria.andLike(User::getUsername, StringLike.strCaonstLike(user.getUsername()));

            criteria.andEqualTo(User::getStatus, user.getStatus());
            criteria.andEqualTo(User::getId, user.getId());

        }
        //2.3 查询
        List<User> Users = baseMapper.selectByExample(example);
        //2.4 封装成pageInfo 对象
        PageInfo<User> pageInfo = new PageInfo<>(Users);

        closeMapper();
        return pageInfo;
    }


    @Override
    public int assignRoles(String uid, String rids[]) {


        int row = 0;

        initMapper();

        //1. 先中间表的数据按照用户ID删除。

        UserRole userRole = new UserRole();

        userRole.setUserId(uid);

        userRoleMapper.delete(userRole);

        //2.分配

        for (int i = 0; i < rids.length; ++i) {

            row += userRoleMapper.insert(new UserRole(rids[i], uid));
        }


        closeMapper();

        return row;
    }


    public int assignRoles(String uid, Set<Role> roles) {


        int row = 0;

        initMapper();

        //1. 先中间表的数据按照用户ID删除。
//
//        UserRole userRole = new UserRole();
//
//        userRole.setUserId(uid);
//
//        userRoleMapper.delete(userRole);

        userRoleMapper.deleteByFieldList(UserRole::getUserId, Arrays.asList(uid));
        //2.分配

        for (Role role:roles) {

            row += userRoleMapper.insert(new UserRole(role.getId(), uid));
        }


        closeMapper();

        return row;
    }

    @Override
    public int UnassignRoles(String uid, String[] rids) {

        int row = 0;

        initMapper();


        for (int i = 0; i < rids.length; ++i) {

            row += userRoleMapper.delete(new UserRole(rids[i], uid));
        }


        closeMapper();

        return row;
    }



    @Override
    public User checkLogin(String mobile,String password)
    {

        initMapper();

        //1. 先查询手机号
        User user = userMapper.selectByMobileUser(mobile);

        if(user ==null)
        {
            return  null;
        }

        //2. 按照密码

       if(user.getPassword().equals(password))
       {
           return user;
       }

       closeMapper();

      return  null;

    }
}
